#pragma once

#include "Property.h"
#include "CompositeProperty.h"
#include "ObjectProperty.h"
#include "PropertyString.h"
#include "Types.h"
#include "Decimal.h"

#include <MyFC/CheckBox.h>
#include <MyFC/ColorBox.h>

namespace My {

/**
 * Specialization for T = String
 */
template <>
bool DLL_API TypedControlBase<String>::GetText(String & s);

template <>
void DLL_API TypedControlBase<String>::SetText(const String & s);

/** 
 * Specialization for T = Size
 */
template <>
bool DLL_API TypedControlBase<Size>::GetText(String &);

template <>
void DLL_API TypedControlBase<Size>::SetText(const String &);

/**
 * Specialization for T = bool, uses checkbox control.
 */
template <> 
class DLL_API TypedControlBase<bool> : public CheckBox {
public:
	TypedControlBase(BasicProperty<bool> &, const EditableList &);
public:
	virtual State GetState() const;
	virtual void HandleClick();
	virtual void HandleUpdateUI();
private:
	BasicProperty<bool> &	m_Property;
	EditableList			m_Objects;
};

/**
 * Specialization for T = ByteColor, uses colorbox control.
 */
template <> 
class DLL_API TypedControlBase<ByteColor> : public ColorBox {
public:
	TypedControlBase(BasicProperty<ByteColor> &, const EditableList &);
public:
	virtual bool GetColor(COLORREF &) const;
	virtual void SetColor(COLORREF);
	virtual void HandleUpdateUI();
private:
	BasicProperty<ByteColor> &	m_Property;
	EditableList				m_Objects;
};

template <>
class DLL_API Property<Span> :	public StructProperty<Span>
{
public:
	Property<int>	First;
	Property<int>	Last;
public:
	Property();
	virtual void Init();
};

template <>
class DLL_API Property<Extent> : public StructProperty<Extent>
{
public:
	Property<size_t>	Width;
	Property<size_t>	Height;
public:
	Property();
	virtual void Init();
};

template <>
class DLL_API Property< point<float> > : public StructProperty< point<float> >
{
public:
	// Decimal<float,3> prints exactly 3 digits after the decimal point,
	// otherwise a user will see numbers, which absolute value is less than 10, 
	// with 5 digits after the decimal point, and larger numbers with lesser precision.
	Property< Decimal<float,3> > X, Y;
//	Property<float> X, Y;
public:
	Property();
public:
	virtual const PropertyMap * GetSubProperties(const EditableList &) const
		{ return 0; }
	virtual Widget * CreateControl(const EditableList &);
	virtual void FreeControl(Widget *);
	virtual void Init();
};

} // My

